<template>
  <div class="tolerance-design">
    <!-- 顶部进度条 -->
    <div class="progress-section">
      <div class="progress-bar">
        <div class="progress-fill" :style="{ width: calculationProgress + '%' }"></div>
        <div class="progress-text">{{ calculationProgress }}%</div>
      </div>
    </div>

    <div class="page-grid">
      <!-- 左侧：结果文件表格 -->
      <div class="left-pane">
        <h3 class="section-title">结果文件</h3>
        <div class="result-table">
          <div class="table-header">
            <div class="th col-id">点位编号</div>
            <div class="th col-pos">点位坐标</div>
            <div class="th col-selected">是否选中</div>
            <div class="th col-threshold">推荐容差阈值（μm）</div>
          </div>
          <div class="table-body">
            <div class="tr" v-for="row in rows" :key="row.id">
              <div class="td col-id">{{ row.id }}</div>
              <div class="td col-pos">{{ row.position }}</div>
              <div class="td col-selected">{{ row.selected ? '是' : '否' }}</div>
              <div class="td col-threshold">{{ row.threshold }}</div>
            </div>
            <div v-if="rows.length === 0" class="table-empty">暂无数据</div>
          </div>
        </div>
      </div>

      <!-- 右侧：日志区域 -->
      <div class="right-pane">
        <div class="section-header log-section-header">
          <h3 class="section-title">日志</h3>
        </div>
        <div class="log-container">
          <div class="log-content">
            <div class="log-entry" v-for="(entry, idx) in logEntries" :key="idx">
              <span class="log-time">{{ entry.time }}</span>
              <span class="log-message" :class="entry.type">{{ entry.message }}</span>
            </div>
            <div v-if="logEntries.length === 0" class="log-empty">暂无日志</div>
          </div>
        </div>
      </div>
    </div>
  </div>

</template>

<script setup>
import { ref, onUnmounted } from 'vue'
import { useCalculationStore } from '@/stores/calculation'
import { startCalculation, tableData } from '@/api/tolerance'
import { getTaskStatus as getTaskStatusAPI } from '@/api/task'
import { getLog as getLogAPI } from '@/api/log'
import toast from '@/utils/toast'

// 使用Pinia store
const calculationStore = useCalculationStore()

// 进度
const calculationProgress = ref(0)

// 结果数据（示例）
const rows = ref([])

// 日志
const logEntries = ref([])

// 轮询定时器
let pollingTimer = null

// 拉取日志（去重）
const fetchLogs = async (taskId) => {
  try {
    const logResponse = await getLogAPI(taskId)
    if (logResponse && logResponse.logs) {
      logResponse.logs.forEach(logString => {
        const logMatch = logString.match(/^(\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2},\d{3}) - (\w+) - (.+)$/)
        if (logMatch) {
          const [, timestamp, level, message] = logMatch
          const timeStr = timestamp.replace(',', '.').replace(' ', 'T') + 'Z'
          const logTime = new Date(timeStr).toLocaleTimeString()
          let logType = 'info'
          if (level === 'ERROR') logType = 'error'
          else if (level === 'WARNING') logType = 'warning'
          else if (level === 'SUCCESS') logType = 'success'
          const exists = logEntries.value.some(e => e.time === logTime && e.message === message.trim())
          if (!exists) {
            logEntries.value.push({ time: logTime, message: message.trim(), type: logType })
          }
        } else {
          const exists = logEntries.value.some(e => e.message === logString.trim())
          if (!exists) {
            logEntries.value.push({ time: new Date().toLocaleTimeString(), message: logString.trim(), type: 'info' })
          }
        }
      })
    }
  } catch (e) {
    // 日志失败不影响主流程
  }
}

// 轮询任务状态
const pollTaskStatus = async (taskId) => {
  const maxAttempts = 300
  let attempts = 0
  let pollInterval = 1000
  let lastProgress = 0
  const poll = async () => {
    try {
      attempts++
      const res = await getTaskStatusAPI(taskId)

      // 更新进度
      if (typeof res.progress === 'number') {
        calculationProgress.value = Math.max(0, Math.min(100, Math.round(res.progress)))
      }

      // 拉取日志
      fetchLogs(taskId)

      if (calculationProgress.value > lastProgress) {
        lastProgress = calculationProgress.value
        pollInterval = 1000
      } else {
        pollInterval = Math.min(pollInterval * 1.5, 10000)
      }

      if (res.status === 'completed' || calculationProgress.value >= 100) {
        calculationProgress.value = 100
        calculationStore.completeCalculation()
        toast.success('计算完成', '容差设计已完成，可以查看结果', 3000)
        try {
          // 填充表格数据
          const tableRes = await tableData(taskId)
          if (tableRes && Array.isArray(tableRes.rows)) {
            rows.value = tableRes.rows.map((r, idx) => ({
              id: r.id ?? `P-${idx + 1}`,
              position: r.position ?? '',
              selected: !!r.selected,
              threshold: r.threshold ?? ''
            }))
          }
        } catch (e) { }
        return
      }

      if (res.status === 'failed') {
        throw new Error(res.error || '计算任务失败')
      }

      if (attempts < maxAttempts) {
        pollingTimer = setTimeout(poll, pollInterval)
      } else {
        throw new Error('计算超时，请稍后重试')
      }
    } catch (error) {
      calculationStore.resetCalculation()
      toast.error('计算失败', error.message || '网络异常', 4000)
      logEntries.value.push({ time: new Date().toLocaleTimeString(), message: `任务状态检查失败: ${error.message}`, type: 'error' })
    }
  }
  logEntries.value.push({ time: new Date().toLocaleTimeString(), message: `开始监控任务状态，任务ID: ${taskId}`, type: 'info' })
  poll()
}

// 暴露（保持与其他页面一致的对外API）
const startDesign = async () => {
  // 标记开始计算
  calculationStore.startCalculation('tolerance-design')
  logEntries.value.push({
    time: new Date().toLocaleTimeString(),
    message: '开始调用容差设计计算接口...',
    type: 'info'
  })

  try {
    const res = await startCalculation()
    logEntries.value.push({
      time: new Date().toLocaleTimeString(),
      message: '计算任务已创建',
      type: 'success'
    })
    if (res && (res.task_id || res.taskId)) {
      const taskId = res.task_id || res.taskId
      await pollTaskStatus(taskId)
    }
  } catch (error) {
    logEntries.value.push({
      time: new Date().toLocaleTimeString(),
      message: `计算启动失败: ${error?.message || '接口异常'}`,
      type: 'error'
    })
    // 失败时重置状态
    calculationStore.resetCalculation()
  }
}

// 卸载清理
onUnmounted(() => {
  if (pollingTimer) {
    clearTimeout(pollingTimer)
    pollingTimer = null
  }
})
const downloadResults = async () => { }

defineExpose({
  startDesign,
  downloadResults
})
</script>

<style scoped>
.tolerance-design {
  height: 100%;
  color: #ffffff;
}

.progress-section {
  margin-bottom: 20px;
}

.progress-bar {
  position: relative;
  width: 100%;
  height: 18px;
  background: #2d2d2d;
  border-radius: 8px;
  overflow: hidden;
  box-shadow: inset 0 2px 8px rgba(0, 0, 0, 0.2);
  border: 1px solid #444;
}

.progress-fill {
  height: 100%;
  background: #485FD4;
  border-radius: 6px;
  transition: width 0.8s cubic-bezier(0.4, 0, 0.2, 1);
}

.progress-text {
  position: absolute;
  left: 50%;
  top: 50%;
  transform: translate(-50%, -50%);
  color: #ffffff;
  font-weight: 700;
  font-size: 14px;
}

.page-grid {
  display: grid;
  grid-template-columns: 1.6fr 1fr;
  gap: 40px;
}

.left-pane,
.right-pane {
  display: flex;
  flex-direction: column;
}

.section-title {
  font-size: 16px;
  font-weight: 600;
  color: #ffffff;
  margin: 0 0 12px 0;
}

.result-table {
  background-color: #2a2a2a;
  border-radius: 8px;
  border: 1px solid #3a3a3a;
  height: 445px;
  /* 与右侧日志面板保持一致 */
  display: flex;
  flex-direction: column;
  box-sizing: border-box;
}

.table-header,
.tr {
  display: grid;
  grid-template-columns: 0.8fr 1.2fr 0.8fr 1.2fr;
  align-items: center;
}

.table-header {
  background: #333;
  color: #e0e0e0;
  padding: 10px 14px;
  border-bottom: 1px solid #3a3a3a;
}

.th {
  font-size: 13px;
  font-weight: 600;
}

.table-body .tr {
  padding: 12px 14px;
  border-bottom: 1px solid #3a3a3a;
}

.table-body {
  overflow-y: auto;
  flex: 1;
}

.table-body .tr:last-child {
  border-bottom: none;
}

.td {
  font-size: 13px;
  color: #e6e6e6;
}

.table-empty {
  padding: 24px;
  text-align: center;
  color: #9aa0a6;
}

.log-section-header {
  margin-bottom: 12px;
}

.log-container {
  height: 400px;
  box-sizing: border-box;
}

.log-content {
  width: 100%;
  height: 100%;
  background: #2d2d2d;
  border-radius: 8px;
  padding: 16px;
  overflow-y: auto;
  border: 1px solid #3a3a3a;
}

.log-entry {
  display: flex;
  gap: 10px;
  padding: 6px 0;
}

.log-time {
  color: #6c757d;
  font-weight: 500;
  min-width: 70px;
}

.log-message {
  color: #ffffff;
  flex: 1;
}

.log-message.info {
  color: #17a2b8;
}

.log-message.success {
  color: #28a745;
}

.log-message.warning {
  color: #ffc107;
}

.log-message.error {
  color: #dc3545;
}

.log-empty {
  color: #9aa0a6;
  text-align: center;
  padding-top: 120px;
}
</style>
